Option Strict Off
Option Explicit On

Imports System.IO
Imports Microsoft.Win32
Imports System.Runtime.InteropServices
Imports System
Imports System.Threading
Friend Module mod_BikiUSB
    Friend Declare Function FT_GetNumberOfDevices Lib "ftd2xx.dll" Alias "FT_ListDevices" (ByRef lngNumberOfDevices As Integer, ByVal pvArg2 As String, ByVal lngFlags As Integer) As FT_return
    Friend Declare Function FT_GetDeviceString Lib "ftd2xx.dll" Alias "FT_ListDevices" (ByVal lngDeviceIndex As Integer, ByVal lpszDeviceString As String, ByVal lngFlags As Integer) As FT_return
    Friend Declare Function FT_GetDeviceInfo Lib "ftd2xx.dll" (ByVal lngHandle As Integer, ByRef lngFT_Type As Integer, ByRef lngID As Integer, ByVal pucSerialNumber As String, ByVal pucDescription As String, ByRef pvDummy As Byte) As FT_return
    Friend Declare Function FT_CreateDeviceInfoList Lib "ftd2xx.dll" (ByRef lngCount As Integer) As FT_return
    Friend Declare Function FT_GetDeviceInfoDetail Lib "ftd2xx.dll" (ByVal dwIndex As Short, ByRef lpdwFlags As Integer, ByRef lpdwType As Integer, ByRef lpdwID As Integer, ByRef lpdwLocID As Integer, ByRef pcSerialNumber As String, ByRef pcDescription As String, ByRef ftHandle As Integer) As FT_return

    '===========================================================================================================================
    ' Declarations for functions in ftd2xx.dll:
    '===========================================================================================================================
    Friend Declare Function FT_OpenByIndex Lib "ftd2xx.dll" Alias "FT_Open" (ByVal intDeviceNumber As Integer, ByRef lngHandle As Integer) As FT_return
    Friend Declare Function FT_OpenBySerialNumber Lib "ftd2xx.dll" Alias "FT_OpenEx" (ByRef SerialNumber As String, ByVal lngFlags As Integer, ByRef lngHandle As Integer) As FT_return
    Friend Declare Function FT_OpenByDescription Lib "ftd2xx.dll" Alias "FT_OpenEx" (ByVal Description As String, ByVal lngFlags As Integer, ByRef lngHandle As Integer) As FT_return
    Friend Declare Function FT_Close Lib "ftd2xx.dll" (ByVal lngHandle As Integer) As FT_return
    Friend Declare Function FT_Read_String Lib "ftd2xx.dll" Alias "FT_Read" (ByVal lngHandle As Integer, ByVal lpvBuffer As String, ByVal lngBufferSize As Integer, ByRef lngBytesReturned As Integer) As FT_return
    Friend Declare Function FT_Write_String Lib "ftd2xx.dll" Alias "FT_Write" (ByVal lngHandle As Integer, ByVal lpvBuffer As String, ByVal lngBufferSize As Integer, ByRef lngBytesWritten As Integer) As FT_return
    Friend Declare Function FT_Read_Bytes Lib "ftd2xx.dll" Alias "FT_Read" (ByVal lngHandle As Integer, ByRef lpvBuffer As Byte, ByVal lngBufferSize As Integer, ByRef lngBytesReturned As Integer) As FT_return
    Friend Declare Function FT_Write_Bytes Lib "ftd2xx.dll" Alias "FT_Write" (ByVal lngHandle As Integer, ByRef lpvBuffer As Byte, ByVal lngBufferSize As Integer, ByRef lngBytesWritten As Integer) As FT_return
    Friend Declare Function FT_SetBaudRate Lib "ftd2xx.dll" (ByVal lngHandle As Integer, ByVal lngBaudRate As Integer) As FT_return
    Friend Declare Function FT_SetDivisor Lib "ftd2xx.dll" (ByVal lngHandle As Integer, ByVal intDivisor As Integer) As FT_return
    Friend Declare Function FT_SetDataCharacteristics Lib "ftd2xx.dll" (ByVal lngHandle As Integer, ByVal byWordLength As FT_Bits, ByVal byStopBits As FT_Stop_Bits, ByVal byParity As FT_Parity) As FT_return
    Friend Declare Function FT_SetFlowControl Lib "ftd2xx.dll" (ByVal lngHandle As Integer, ByVal intFlowControl As FT_Flow, ByVal byXonChar As Byte, ByVal byXoffChar As Byte) As FT_return
    Friend Declare Function FT_ResetDevice Lib "ftd2xx.dll" (ByVal lngHandle As Integer) As FT_return
    Friend Declare Function FT_SetDtr Lib "ftd2xx.dll" (ByVal lngHandle As Integer) As FT_return
    Friend Declare Function FT_ClrDtr Lib "ftd2xx.dll" (ByVal lngHandle As Integer) As FT_return
    Friend Declare Function FT_SetRts Lib "ftd2xx.dll" (ByVal lngHandle As Integer) As FT_return
    Friend Declare Function FT_ClrRts Lib "ftd2xx.dll" (ByVal lngHandle As Integer) As FT_return
    Friend Declare Function FT_GetModemStatus Lib "ftd2xx.dll" (ByVal lngHandle As Integer, ByRef lngModemStatus As Integer) As FT_return
    Friend Declare Function FT_SetChars Lib "ftd2xx.dll" (ByVal lngHandle As Integer, ByVal byEventChar As Byte, ByVal byEventCharEnabled As Byte, ByVal byErrorChar As Byte, ByVal byErrorCharEnabled As Byte) As FT_return
    Friend Declare Function FT_Purge Lib "ftd2xx.dll" (ByVal lngHandle As Integer, ByVal lngMask As FT_Purg) As FT_return
    Friend Declare Function FT_SetTimeouts Lib "ftd2xx.dll" (ByVal lngHandle As Integer, ByVal lngReadTimeout As Integer, ByVal lngWriteTimeout As Integer) As FT_return
    Friend Declare Function FT_GetQueueStatus Lib "ftd2xx.dll" (ByVal lngHandle As Integer, ByRef lngRxBytes As Integer) As FT_return
    Friend Declare Function FT_GetLatencyTimer Lib "ftd2xx.dll" (ByVal lngHandle As Integer, ByRef ucTimer As Byte) As FT_return
    Friend Declare Function FT_SetLatencyTimer Lib "ftd2xx.dll" (ByVal lngHandle As Integer, ByVal ucTimer As Byte) As FT_return
    Friend Declare Function FT_GetBitMode Lib "ftd2xx.dll" (ByVal lngHandle As Integer, ByRef ucMode As Byte) As FT_return
    Friend Declare Function FT_SetBitMode Lib "ftd2xx.dll" (ByVal lngHandle As Integer, ByVal ucMask As Byte, ByVal ucEnable As Byte) As FT_return
    Friend Declare Function FT_SetUSBParameters Lib "ftd2xx.dll" (ByVal lngHandle As Integer, ByVal lngInTransferSize As Integer, ByVal lngOutTransferSize As Integer) As FT_return
    Friend Declare Function FT_SetBreakOn Lib "ftd2xx.dll" (ByVal lngHandle As Integer) As FT_return
    Friend Declare Function FT_SetBreakOff Lib "ftd2xx.dll" (ByVal lngHandle As Integer) As FT_return
    Friend Declare Function FT_GetStatus Lib "ftd2xx.dll" (ByVal lngHandle As Integer, ByRef lngamountInRxQueue As Integer, ByRef lngAmountInTxQueue As Integer, ByRef lngEventStatus As Integer) As FT_return

    Friend Declare Function FT_SetEventNotification Lib "ftd2xx.dll" (ByVal lngHandle As Integer, ByVal lngEventMask As FT_Events, ByVal lngEvent As Integer) As FT_return

    '==============================================================
    'Declarations for the EEPROM-accessing functions in ftd2xx.dll:
    '==============================================================
    'UPGRADE_WARNING: Structure FT_PROGRAM_DATA may require marshalling attributes to be passed as an argument in this Declare statement. Click for more: 'ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?keyword="C429C3A5-5D47-4CD9-8F51-74A1616405DC"'
    Friend Declare Function FT_CyclePort Lib "ftd2xx.dll" (ByVal lngHandle As Integer) As FT_return
    Friend Declare Function FT_EraseEE Lib "ftd2xx.dll" (ByVal lngHandle As Integer) As FT_return
    Friend Declare Function FT_EE_Program Lib "ftd2xx.dll" (ByVal lngHandle As Integer, ByRef lpData As FT_PROGRAM_DATA) As FT_return
    Friend Declare Function FT_EE_Read Lib "ftd2xx.dll" (ByVal lngHandle As Integer, ByRef lpData As FT_PROGRAM_DATA) As FT_return
    Friend Declare Function FT_EE_ReadEx Lib "ftd2xx.dll" (ByVal lngHandle As Integer, ByRef lpData As FT_PROGRAM_DATA, ByVal Manufacturer As String, ByVal ManufacturerId As String, ByVal Description As String, ByVal SerialNumber As String) As FT_return
    Friend Declare Function FT_EE_ProgramEx Lib "ftd2xx.dll" (ByVal lngHandle As Integer, ByRef lpData As FT_PROGRAM_DATA, ByVal Manufacturer As String, ByVal ManufacturerId As String, ByVal Description As String, ByVal SerialNumber As String) As FT_return
    Private Declare Function FT_EE_UASize Lib "ftd2xx.dll" (ByVal lngHandle As Integer, ByRef lpdwSize As Integer) As FT_return
    Private Declare Function FT_EE_UAWrite Lib "ftd2xx.dll" (ByVal lngHandle As Integer, ByVal pucData() As Byte, ByVal dwDataLen As Integer) As FT_return
    Private Declare Function FT_EE_UARead Lib "ftd2xx.dll" (ByVal lngHandle As Integer, ByVal pucData() As Byte, ByVal dwDataLen As Integer, ByRef lpdwBytesRead As Integer) As FT_return


    '====================================================================
    'Type definition as equivalent for C-structure "ft_program_data" used
    'in FT_EE_READ and FT_EE_WRITE;
    'ATTENTION! The variables "Manufacturer", "ManufacturerID",
    '"Description" and "SerialNumber" are passed as POINTERS to
    'locations of Bytearrays. Each Byte in these arrays will be
    'filled with one character of the whole string.
    '(See below, calls to "agGetAddressForObject")
    '=====================================================================
    Friend Structure FT_PROGRAM_DATA
        Dim Signature1 As UInt32       ' Header - must be 0x00000000
        Dim Signature2 As UInt32       ' Header - must be 0xffffffff
        Dim Version As UInt32          ' Header - FT_PROGRAM_DATA version
        ' 0 = original
        ' 1 = FT2232C extensions
        ' 2 = FT232R extensions
        Dim VendorId As UInt16           ' 0x0403
        Dim ProductId As UInt16          ' 0x6001
        <MarshalAs(UnmanagedType.LPStr)> _
        Dim Manufacturer As String      ' "FTDI"
        <MarshalAs(UnmanagedType.LPStr)> _
        Dim ManufacturerId As String    ' "FT"
        <MarshalAs(UnmanagedType.LPStr)> _
        Dim Description As String       ' "USB HS Serial Converter"
        <MarshalAs(UnmanagedType.LPStr)> _
        Dim SerialNumber As String      ' "FT000001" if fixed, or NULL
        Dim MaxPower As UInt16           ' 0 < MaxPower <= 500
        Dim PnP As UInt16                ' 0 = disabled, 1 = enabled
        Dim SelfPowered As UInt16        ' 0 = bus powered, 1 = self powered
        Dim RemoteWakeup As UInt16       ' 0 = not capable, 1 = capable
        '
        ' Rev4 extensions
        '
        Dim Rev4 As Byte                ' non-zero if Rev4 chip, zero otherwise
        Dim IsoIn As Byte               ' non-zero if in endpoint is isochronous
        Dim IsoOut As Byte              ' non-zero if out endpoint is isochronous
        Dim PullDownEnable As Byte      ' non-zero if pull down enabled
        Dim SerNumEnable As Byte        ' non-zero if serial number to be used
        Dim USBVersionEnable As Byte    ' non-zero if chip uses USBVersion
        Dim USBVersion As UInt16         ' BCD (0x0200 => USB2)
        '
        ' FT2232C extensions
        '
        Dim Rev5 As Byte                ' non-zero if Rev5 chip, zero otherwise
        Dim IsoInA As Byte              ' non-zero if in endpoint is isochronous
        Dim IsoInB As Byte              ' non-zero if in endpoint is isochronous
        Dim IsoOutA As Byte             ' non-zero if out endpoint is isochronous
        Dim IsoOutB As Byte             ' non-zero if out endpoint is isochronous
        Dim PullDownEnable5 As Byte     ' non-zero if pull down enabled
        Dim SerNumEnable5 As Byte       ' non-zero if serial number to be used
        Dim USBVersionEnable5 As Byte   ' non-zero if chip uses USBVersion
        Dim USBVersion5 As UInt16        ' BCD (0x0200 => USB2)
        Dim AIsHighCurrent As Byte      ' non-zero if interface is high current
        Dim BIsHighCurrent As Byte      ' non-zero if interface is high current
        Dim IFAIsFifo As Byte           ' non-zero if interface is 245 FIFO
        Dim IFAIsFifoTar As Byte        ' non-zero if interface is 245 FIFO CPU target
        Dim IFAIsFastSer As Byte        ' non-zero if interface is Fast serial
        Dim AIsVCP As Byte              ' non-zero if interface is to use VCP drivers
        Dim IFBIsFifo As Byte           ' non-zero if interface is 245 FIFO
        Dim IFBIsFifoTar As Byte        ' non-zero if interface is 245 FIFO CPU target
        Dim IFBIsFastSer As Byte        ' non-zero if interface is Fast serial
        Dim BIsVCP As Byte              ' non-zero if interface is to use VCP drivers
        '
        ' FT232R extensions
        '
        Dim UseExtOsc As Byte           ' Use External Oscillator
        Dim HighDriveIOs As Byte        ' High Drive I/Os
        Dim EndpointSize As Byte        ' Endpoint size
        Dim PullDownEnableR As Byte     ' non-zero if pull down enabled
        Dim SerNumEnableR As Byte       ' non-zero if serial number to be used
        Dim InvertTXD As Byte           ' non-zero if invert TXD
        Dim InvertRXD As Byte           ' non-zero if invert RXD
        Dim InvertRTS As Byte           ' non-zero if invert RTS
        Dim InvertCTS As Byte           ' non-zero if invert CTS
        Dim InvertDTR As Byte           ' non-zero if invert DTR
        Dim InvertDSR As Byte           ' non-zero if invert DSR
        Dim InvertDCD As Byte           ' non-zero if invert DCD
        Dim InvertRI As Byte            ' non-zero if invert RI
        Dim Cbus0 As Byte               ' Cbus Mux control
        Dim Cbus1 As Byte               ' Cbus Mux control
        Dim Cbus2 As Byte               ' Cbus Mux control
        Dim Cbus3 As Byte               ' Cbus Mux control
        Dim Cbus4 As Byte               ' Cbus Mux control
        Dim RIsVCP As Byte              ' non-zero if using D2XX drivers

        Sub New(ByVal Serial As Integer)
            If Serial = 0 Then
                SerNumEnableR = 0
            Else
                SerNumEnableR = 1
            End If
            SerialNumber = "BK3.3-RLTM"
            Signature1 = 0
            Signature2 = &HFFFFFFFFUI
            Version = 2
            SelfPowered = 0
            AIsHighCurrent = 0
            AIsVCP = 0
            BIsHighCurrent = 0
            BIsVCP = 0
            Cbus0 = 10
            Cbus1 = 10
            Cbus2 = 10
            Cbus3 = 10
            Cbus4 = 0
            Description = "BikiR0M USB Interface"
            EndpointSize = 64
            HighDriveIOs = 1
            IFAIsFastSer = 0
            IFAIsFifo = 0
            IFAIsFifoTar = 0
            IFBIsFastSer = 0
            IFBIsFifo = 0
            IFBIsFifoTar = 0
            InvertCTS = 0
            InvertDCD = 0
            InvertDSR = 0
            InvertDTR = 0
            InvertRI = 0
            InvertRTS = 0
            InvertRXD = 0
            InvertTXD = 0
            IsoIn = 0
            IsoInA = 0
            IsoInB = 0
            IsoOut = 0
            IsoOutA = 0
            IsoOutB = 0
            Manufacturer = "BikiRom"
            ManufacturerId = "BR"
            MaxPower = 100
            PnP = 1
            ProductId = &HD599
            PullDownEnable = 0
            PullDownEnable5 = 0
            PullDownEnableR = 0
            RemoteWakeup = 1
            Rev4 = 0
            Rev5 = 0
            RIsVCP = 1
            SerNumEnable = 0
            SerNumEnable5 = 0
            SerNumEnableR = 1
            USBVersion = 272
            USBVersion5 = 0
            USBVersionEnable = 0
            USBVersionEnable5 = 0
            UseExtOsc = 0
            VendorId = 1027
        End Sub

        'Public ReadOnly Property str_Description() As String
        '    Get
        '        Return Marshal.PtrToStringAuto(Description)
        '    End Get
        'End Property
    End Structure

    Friend Enum BikiAction As Integer
        BK_NONE = 0
        BK_MAP1 = &H1
        BK_MAP2 = &H2
        BK_MAP3 = &H4
        BK_CFG = &H8
        BK_ALL = &H10
        BK_EEPROM = &H20
    End Enum
    ''' <summary>
    ''' This enumator defines Integer values in byte offset from zero of the USB FT 232's EEPROM space
    ''' </summary>
    ''' <remarks></remarks>
    Friend Enum Biki_USBvars As Short
        UV_Baud = 0
        UV_EcuFLASH_CRC = 2
        UV_BikEEPROM_CRC = 6
        UV_EcuFLASH_CRC_MAP_2 = &HA
        UV_EcuFLASH_CRC_MAP_3 = &HE
        UV_FirmWare = &H12
        UV_BikPROG = &H14
    End Enum

    Friend Enum FT_return As Short
        FT_OK = 0
        FT_INVALID_HANDLE = 1
        FT_DEVICE_NOT_FOUND = 2
        FT_DEVICE_NOT_OPENED = 3
        FT_IO_ERROR = 4
        FT_INSUFFICIENT_RESOURCES = 5
        FT_INVALID_PARAMETER = 6
        FT_INVALID_BAUD_RATE = 7
        FT_DEVICE_NOT_OPENED_FOR_ERASE = 8
        FT_DEVICE_NOT_OPENED_FOR_WRITE = 9
        FT_FAILED_TO_WRITE_DEVICE = 10
        FT_EEPROM_READ_FAILED = 11
        FT_EEPROM_WRITE_FAILED = 12
        FT_EEPROM_ERASE_FAILED = 13
        FT_EEPROM_NOT_PRESENT = 14
        FT_EEPROM_NOT_PROGRAMMED = 15
        FT_INVALID_ARGS = 16
        FT_OTHER_ERROR = 17
        FT_IO_TIMEOUT = 32
        FT_IO_FAILED = 33
    End Enum
    Friend Enum BK_return As Short
        BK_OK = 0
        BK_IO_ERROR_USB = 1
        BK_IO_ERROR_BIK = 2
        BK_DEVICE_NOT_FOUND = 3
        BK_FAILED_INIT = 4
        BK_FAILED_CMD = 5
        BK_ERROR_CATCH = 6
        BK_IO_CRC_FAILED = 7
        BK_FAILED_ERASE = 8
        BK_TH_CANCELLED = 9
        BK_FIRMWARE = 10
        BK_BIKISOFT_REQUIRES_UPDATE = 11
        BK_FIRMWARE_REQUIRES_UPDATE = 13
        BK_NOT_CONNECTED = 12
        BK_CONSULT_NOINIT = 14
        BK_CONSULT_FAILED = 15
        BK_IO_TIMEOUT = 16
        BK_IO_BAD_HEADERS = 17
        BK_ATMEL_REQUIRES_REFLASH_8MHZ = 18
        BK_ATMEL_REQUIRES_REFLASH_12MHZ = 19
        BK_ATMEL_REQUIRES_REFLASH_16MHZ = 20
    End Enum
    Friend Enum FT_Bits As Short
        FT_BITS_8 = 8
        FT_BITS_7 = 7
    End Enum
    Friend Enum FT_Stop_Bits As Short
        FT_STOP_BITS_1 = 0
        FT_STOP_BITS_1_5 = 1
        FT_STOP_BITS_2 = 2
    End Enum
    Friend Enum FT_Parity As Short
        FT_PARITY_NONE = 0
        FT_PARITY_ODD = 1
        FT_PARITY_EVEN = 2
        FT_PARITY_MARK = 3
        FT_PARITY_SPACE = 4
    End Enum
    Friend Enum FT_Flow As Short
        FT_FLOW_NONE = &H0S
        FT_FLOW_RTS_CTS = &H100S
        FT_FLOW_DTR_DSR = &H200S
        FT_FLOW_XON_XOFF = &H400S
    End Enum
    Friend Enum FT_Purg As Short
        FT_PURGE_RX = 1
        FT_PURGE_TX = 2
    End Enum
    Friend Enum FT_Events As Integer
        FT_EVENT_RXCHAR = 1
        FT_EVENT_MODEM_STATUS = 2
    End Enum
    ' Flags for FT_OpenEx
    Const FT_OPEN_BY_SERIAL_NUMBER As Short = 1
    Const FT_OPEN_BY_DESCRIPTION As Short = 2

    ' Flags for FT_ListDevices
    Friend Const FT_LIST_BY_NUMBER_ONLY As Integer = &H80000000
    Const FT_LIST_BY_INDEX As Integer = &H40000000
    Const FT_LIST_ALL As Integer = &H20000000

    ' USB Info class and Handle
    Friend lngHandle As Integer
    Friend m_BikiInfo As New Comm_BikiInfo

    ' USB Recive Events
    Friend m_UsbRxEvent2 As New AutoResetEvent(True)
    Friend m_UsbTxEvent As New AutoResetEvent(True)
    Friend m_UsbTxEvent2 As New AutoResetEvent(True)
    Friend m_UsbRxEvent As New AutoResetEvent(False)
    Friend m_UsbFlashDataEvent As New AutoResetEvent(False)
    Friend m_UsbEEpromDataEvent As New AutoResetEvent(False)
    Friend m_UsbLastCmdStatusEvent As New AutoResetEvent(False)
    Friend m_UsbCRCFailedEvent As New AutoResetEvent(False)
    Friend m_UsbHeadersFailedEvent As New AutoResetEvent(False)
    Friend m_UsbConsultEvent As New AutoResetEvent(False)
    Friend m_UsbStreamEvent As New AutoResetEvent(False)
    Friend m_UsbGeneralSpecificEvent As New AutoResetEvent(False)

    ' USB Primary Recieve Buffer and threads
    Friend m_UsbRx As New ArrayList(4000)
    Friend m_UsbRxThread As Thread

    ' USB Recieve Buffer Queues, Complete Frames per item.
    Friend m_UsbFlashDataBuffer As New Queue(10)
    Friend m_UsbEEpromDataBuffer As New Queue(10)
    Friend m_UsbLastCmdStatusBuffer As New Queue(10)
    Friend m_UsbConsultPassBuffer As Byte() = Nothing
    Friend m_UsbConsultIntegratedBuffer As New Queue(10)
    Friend m_UsbGeneralSpecificBuffer As New Queue(10)
    Friend m_UsbRandomBytesBuffer As New ArrayList

    Friend m_ConsultReceiveBytes As Integer = -1

    ' Depreciated Variables
    Friend g_timeouts As Integer = 200
    Friend g_packetSize As Integer = 256

    ''' <summary>
    ''' This function can be called whenever, it will only truley initialise when the USB connection is down
    ''' Otherwise rely on timeouts etc to work out if the board is powered on etc
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Friend Function BikiRom_Init(Optional ByVal WaitForBootup As Boolean = True, Optional ByVal device_name As String = "") As BK_return
        Dim f_retry As Byte = 0
        Dim f_Pass As BK_return = BK_return.BK_FAILED_INIT
        Dim f_return(0) As Byte
        Dim rxbytes As Integer

        ' Check the status of the connection
        'If WaitHandle.WaitAny(New WaitHandle() {m_UsbTxEvent, m_UsbRxEvent2}, 5000, True) = WaitHandle.WaitTimeout Then
        '    Return BK_return.BK_IO_TIMEOUT
        'Else
        If lngHandle <> 0 AndAlso FT_GetQueueStatus(lngHandle, rxbytes) <> FT_return.FT_OK Then m_BikiInfo.Initialised = False
        If lngHandle = 0 Or Not m_BikiInfo.Initialised Or (Not IsNothing(m_UsbRxThread) AndAlso Not m_UsbRxThread.IsAlive) Or IsNothing(m_UsbRxThread) Then
            f_Pass = BikiRom_connect(, device_name)
            If f_Pass = BK_return.BK_OK Then
                BikiRom_Reset()
                Thread.Sleep(2000)

                ' send the frame for turning the streaming off.. i want to get a normal return here! no exceptions!
                ' Clear out old events and get to initial states
                m_UsbFlashDataEvent.Reset()
                m_UsbLastCmdStatusEvent.Reset()
                m_UsbEEpromDataEvent.Reset()
                m_UsbFlashDataBuffer.Clear()
                m_UsbEEpromDataBuffer.Clear()
                m_UsbLastCmdStatusBuffer.Clear()
                m_UsbRandomBytesBuffer.Clear()
                m_UsbGeneralSpecificBuffer.Clear()
                m_UsbCRCFailedEvent.Reset()
                m_UsbHeadersFailedEvent.Reset()
                m_UsbTxEvent.Set()
                m_UsbRxEvent2.Set()

                FT_Purge(lngHandle, FT_Purg.FT_PURGE_RX)
                'FT_SetEventNotification(lngHandle, FT_Events.FT_EVENT_RXCHAR, m_UsbRxEvent.SafeWaitHandle.DangerousGetHandle)

                If IsNothing(m_UsbRxThread) Or _
                   (Not IsNothing(m_UsbRxThread) AndAlso Not m_UsbRxThread.IsAlive) _
                Then
                    ' Start the Rx Thread, this will handle all communications from here on in.
                    Dim f_RxThread As New Comm_RxHandle()
                    m_UsbRxThread = New Thread(New ThreadStart(AddressOf f_RxThread.execute))
                    m_UsbRxThread.Name = "USB Rx Thread"
                    m_UsbRxThread.Start()
                End If
                If WaitForBootup Then
                    Try
                        Dim f_Frame As Comm.Comm_Frame

                        m_BikiInfo.reset()
                        If Not m_BikiInfo.getBikiromInfo() Then Throw New Exception("Failed to get Bikirom Infomation")

                        f_Frame = New Comm.Comm_Frame(Comm.Comm_Frame.BikiFrameType.ID_CONSULT_INTEGRATED, , Comm.Comm_Frame.BikiFrameAction.CMD_STOP)
                        f_Frame.Send()

                    Catch exUsb As USB_exceptions
                        m_BikiInfo.Initialised = False
                        Return BK_return.BK_FAILED_INIT
                    Catch exComm As Comm_Exceptions
                        m_BikiInfo.Initialised = False
                        Return BK_return.BK_FAILED_INIT
                    Catch exRandom As Exception
                        m_BikiInfo.Initialised = False
                        Return BK_return.BK_FAILED_INIT
                    End Try
                End If

                m_BikiInfo.Initialised = True
                m_UsbTxEvent.Set()
                m_UsbRxEvent2.Set()
                Return BK_return.BK_OK
            Else
                m_UsbTxEvent.Set()
                m_UsbRxEvent2.Set()
                Return f_Pass
            End If
        Else
            m_UsbTxEvent.Set()
            m_UsbRxEvent2.Set()
            Return BK_return.BK_OK
        End If

    End Function
    Friend Sub BikiRom_clear()
        m_UsbConsultIntegratedBuffer.Clear()
    End Sub
    Friend Function BikiRom_connect(Optional ByVal Explicit As Boolean = False, Optional ByVal device_name As String = "") As BK_return
        Dim fUsbReturn As FT_return

        If Not Explicit Then
            If lngHandle <> 0 Then
                If FT_ClrRts(lngHandle) = FT_return.FT_OK Then
                    Return BK_return.BK_OK
                Else
                    close_bikirom()
                End If
            End If
        ElseIf lngHandle <> 0 Then
            close_bikirom()
        End If

        If device_name <> "" Then
            fUsbReturn = FT_OpenByDescription(device_name, 2, lngHandle)
        Else
            fUsbReturn = FT_OpenByIndex(0, lngHandle)
        End If

        If fUsbReturn <> FT_return.FT_OK Then
            Return BK_return.BK_DEVICE_NOT_FOUND
        End If

        FT_ClrRts(lngHandle)

        Dim f_Type, f_ID As Integer
        Dim f_Serial As String = ""
        f_Serial = f_Serial.PadLeft(100)
        Dim f_Desc As String = ""
        f_Desc = f_Desc.PadLeft(100)
        FT_GetDeviceInfo(lngHandle, f_Type, f_ID, f_Serial, f_Desc, Nothing)
        m_BikiInfo.SerialNo = f_Serial

        Dim f_baud As UInt16
        GetUsbVariable(Biki_USBvars.UV_Baud, f_baud)
        If f_baud = 250 Or f_baud = 500 Or f_baud = 375 Then
            m_BikiInfo.Baud = f_baud * 1000
        Else
            m_BikiInfo.Baud = 500000
        End If

        Debug.WriteLine(String.Format("USB Connected to {0} at {1} baud", f_Desc, m_BikiInfo.Baud))
        If FT_SetBaudRate(lngHandle, m_BikiInfo.Baud) <> FT_return.FT_OK Then
            GoTo CloseHandle
        End If

        Dim f_OverHeadRx As Integer = m_BikiInfo.MaxRxPacket \ 62
        If m_BikiInfo.MaxRxPacket Mod 62 <> 0 Then f_OverHeadRx += 1

        Dim f_OverHeadTx As Integer = m_BikiInfo.MaxTxPacket \ 62
        If m_BikiInfo.MaxTxPacket Mod 62 <> 0 Then f_OverHeadTx += 1

        If FT_SetUSBParameters(lngHandle, m_BikiInfo.MaxRxPacket + (f_OverHeadRx * 2), m_BikiInfo.MaxTxPacket + (f_OverHeadTx * 2)) <> FT_return.FT_OK Then
            GoTo CloseHandle
        End If
        If FT_SetDataCharacteristics(lngHandle, FT_Bits.FT_BITS_8, FT_Stop_Bits.FT_STOP_BITS_1, FT_Parity.FT_PARITY_NONE) <> FT_return.FT_OK Then
            GoTo CloseHandle
        End If
        If FT_SetFlowControl(lngHandle, FT_Flow.FT_FLOW_NONE, 0, 0) <> FT_return.FT_OK Then
            System.Diagnostics.Debug.WriteLine("SetFlowControl Failed")
            GoTo CloseHandle
        End If
        If FT_SetTimeouts(lngHandle, m_BikiInfo.TimeOut, 0) <> FT_return.FT_OK Then
            System.Diagnostics.Debug.WriteLine("SetTimeouts Failed")
            GoTo CloseHandle
        End If
        Dim lngLatency As Byte = 1
        If FT_SetLatencyTimer(lngHandle, lngLatency) <> FT_return.FT_OK Then
            System.Diagnostics.Debug.WriteLine("SetLatency Failed")
            GoTo CloseHandle
        End If

        FT_ClrRts(lngHandle)

        Return BK_return.BK_OK
        Exit Function
CloseHandle:
        FT_Close(lngHandle)
        Return BK_return.BK_IO_ERROR_BIK
    End Function
    Friend Function usb_read(Optional ByVal RxBytes As Integer = 0) As Byte()
        Dim f_BytesInBuffer As Integer = 0
        FT_GetQueueStatus(lngHandle, f_BytesInBuffer)
        If RxBytes = 0 And f_BytesInBuffer > 0 Then
            Dim retBytes(f_BytesInBuffer - 1) As Byte
            FT_Read_Bytes(lngHandle, retBytes(0), f_BytesInBuffer, RxBytes)
            ReDim Preserve retBytes(RxBytes - 1)
            Return retBytes
        ElseIf RxBytes > 0 Then
            Dim retBytes(2056) As Byte
            FT_Read_Bytes(lngHandle, retBytes(0), RxBytes, RxBytes)
            If RxBytes > 0 Then
                ReDim Preserve retBytes(RxBytes - 1)
                Console.WriteLine("USB Read {0:G} bytes: " & cv_HexFromBytes(retBytes), RxBytes)
                Return retBytes
            Else
                Return Nothing
            End If
        End If
        Return Nothing
    End Function
    Friend Function BikiRom_hexCmd(ByVal Str_ As String, ByRef Return_() As Byte, ByVal retLen As Integer) As Boolean
        Dim f_cmd() As Byte = cv_BytesFromHex(Str_)
        If BikiRom_sndCmd(lngHandle, f_cmd, Return_, f_cmd.Length, retLen) = FT_return.FT_OK Then
            Return True
        Else
            Return False
        End If
    End Function
    ''' <summary>
    ''' Send a command to the bikirom USB device and check it gives the reply given into the function
    ''' </summary>
    ''' <param name="inputStr">Command as a Hex String to send to BikiRom</param>
    ''' <param name="replyStr">BikiRom Reply Hex String validated against</param>
    ''' <returns>True if the replyStr is whats returned</returns>
    ''' <remarks></remarks>
    Friend Function BikiRom_hexCmd(ByVal inputStr As String, ByVal replyStr As String) As Boolean
        Dim f_cmd() As Byte = cv_BytesFromHex(inputStr)
        Dim f_reply() As Byte = cv_BytesFromHex(replyStr)
        Dim f_return(f_reply.Length - 1) As Byte
        Dim f_result As Boolean = True
        If BikiRom_sndCmd(lngHandle, f_cmd, f_return, f_cmd.Length, f_reply.Length) = FT_return.FT_OK Then
            For i As Integer = 0 To UBound(f_reply)
                If f_reply(i) <> f_return(i) Then f_result = False
            Next
            Return f_result
        Else
            Return False
        End If
    End Function
    Friend Function BikiRom_hexCmd(ByVal Str_ As String, ByVal retLen As Integer) As Boolean
        Dim f_cmd() As Byte = cv_BytesFromHex(Str_)
        Dim f_return(0 To retLen) As Byte
        If BikiRom_sndCmd(lngHandle, f_cmd, f_return, f_cmd.Length, retLen) = FT_return.FT_OK Then
            Return True
        Else
            Return False
        End If
    End Function
    Friend Function BikiRom_hexCmd(ByVal Str_ As String) As Boolean
        Dim f_cmd() As Byte = cv_BytesFromHex(Str_)
        Dim f_return(0 To 1) As Byte
        If BikiRom_sndCmd(lngHandle, f_cmd, f_return, f_cmd.Length, 0) = FT_return.FT_OK Then
            Return True
        Else
            Return False
        End If
    End Function
    Friend Function BikiRom_HexCmdAA(ByVal str As String) As Boolean
        Dim f_cmd() As Byte = cv_BytesFromHex(str)
        Dim f_return(0 To 1) As Byte
        If BikiRom_sndCmd(lngHandle, f_cmd, f_return, f_cmd.Length, 1) = FT_return.FT_OK Then
            If f_return(0) = &HAA Then Return True Else Return False
        Else
            Return False
        End If
    End Function
    Friend Function BikiRom_sendCmdd(ByRef Send_() As Byte, ByRef Return_() As Byte, ByVal sendLen As Integer, ByVal retLen As Integer) As Boolean
        If BikiRom_sndCmd(lngHandle, Send_, Return_, sendLen, retLen) = FT_return.FT_OK Then
            BikiRom_sendCmdd = True
        Else
            BikiRom_sendCmdd = False
        End If
    End Function
    Private Function BikiRom_sndCmd(ByRef f_lngHandle As Integer, ByRef Send_() As Byte, ByRef Return_() As Byte, ByVal sendLen As Integer, ByVal retLen As Integer) As FT_return
        Dim f_retCount As Integer
        Dim flTimedout As Boolean = False
        Dim flFatalError As Boolean = False
        Dim lngTotalBytesRead As Integer = 0
        Dim ftStatus As Short
        Dim lngBytesRead As Integer = 0
        Dim byteArray(258) As Byte
        Dim arrayCursor As Short = 0
        Dim i As Short
        Dim fReturn As FT_return = FT_return.FT_OK

        '  If sendLen >= 1 Then
        'FT_Purge(lngHandle, FT_Purg.FT_PURGE_RX + FT_Purg.FT_PURGE_TX)
        'End If
        'Debug.Print ("cmd: " & cv_HexFromString(Send_) & " length: " & sendLen)
        '********************
        '** Send Command Code
        If sendLen >= 1 Then
            fReturn = FT_Write_Bytes(f_lngHandle, Send_(0), sendLen, f_retCount)
            If fReturn <> FT_return.FT_OK Then
                Debug.Write("Error writing bytes to USB CHIP")
                Return fReturn
            End If
        End If
        If retLen <> 0 Then
            flTimedout = False
            flFatalError = False

            '******************
            '** Wait for number of bytes code
            lngTotalBytesRead = 0
            Do
                lngBytesRead = 0
                ftStatus = FT_Read_Bytes(f_lngHandle, byteArray(0), retLen, lngBytesRead)
                ' Debug.Print("FT_Read - send# :" & retLen & " Read: " & lngTotalBytesRead)
                If (ftStatus = FT_return.FT_OK) Or (ftStatus = FT_return.FT_IO_ERROR) Then
                    If lngBytesRead > 0 Then
                        For i = 1 To lngBytesRead
                            Return_(arrayCursor) = byteArray(i - 1)
                            arrayCursor += 1
                        Next
                        lngTotalBytesRead += lngBytesRead
                        retLen -= lngBytesRead
                    Else
                        Return FT_return.FT_IO_TIMEOUT
                        flTimedout = True
                    End If
                Else
                    Return FT_return.FT_IO_FAILED
                    flFatalError = True
                End If
            Loop Until (lngTotalBytesRead >= retLen) Or (flTimedout = True) Or (flFatalError = True)
            'Else
            'FT_Purge(f_lngHandle, FT_Purg.FT_PURGE_RX)
        End If
        '*******************
        '** Return Code
        Return FT_return.FT_OK
    End Function
    Friend Function BikiRom_sendFrame(ByRef iFrame As Comm.Comm_Frame) As FT_return
        Dim f_Written As ULong = 0
        Dim f_return As FT_return = FT_Write_Bytes(lngHandle, iFrame.Data(0), iFrame.Data.Length, f_Written)
doAgain: If f_return = FT_return.FT_OK And f_Written <> iFrame.Data.Length Then
            f_return = FT_Write_Bytes(lngHandle, iFrame.Data(f_Written), iFrame.Data.Length - f_Written, f_Written)
            GoTo doAgain
        End If
        Return f_return
    End Function
    ''' <summary>
    ''' Sends a new BikiSoft Frame, and attempts to receive a response frame if required.
    ''' </summary>
    ''' <param name="iData">Complete Frame</param>
    ''' <param name="oData">Response Frame</param>
    ''' <param name="ReadResponse">If a response is required</param>
    ''' <returns>Physical USB Layer return paramaters</returns>
    ''' <remarks>All Frame layer responses are in the oData and not handled in this layer</remarks>
    ''' 
    Friend Function BikiRom_sendFrame(ByRef iData As Byte(), ByRef oData() As Byte, Optional ByVal ReadResponse As Boolean = True) As BK_return
        Dim f_ReturnLength As Integer = 0
        Dim f_ReturnData() As Byte = Nothing
        Dim f_ReturnStatus As FT_return
        Dim f_GetBytes As UShort
        Dim i As Integer

        If ReadResponse Then
            f_ReturnLength = 6
            ReDim f_ReturnData(5)
        End If

        FT_Purge(lngHandle, FT_Purg.FT_PURGE_RX)

        f_ReturnStatus = BikiRom_sndCmd(lngHandle, iData, f_ReturnData, iData.Length, f_ReturnLength)
        If f_ReturnStatus = FT_return.FT_OK Then
            If f_ReturnData(0) = &HAA And _
               f_ReturnData(1) = &HA5 And _
               f_ReturnData(2) = Comm.Comm_Frame.BikiFrameType.ID_PC _
             Then
                f_GetBytes = (f_ReturnData(4) * &H100) Or f_ReturnData(5) + 4
                Dim f_GetData(f_GetBytes - 1) As Byte
                f_ReturnStatus = BikiRom_sndCmd(lngHandle, Nothing, f_GetData, 0, f_GetBytes)
                If f_ReturnStatus = FT_return.FT_OK Then
                    ReDim Preserve f_ReturnData(5 + f_GetBytes)
                    Array.Copy(f_GetData, 0, f_ReturnData, 6, f_GetBytes)
                    oData = f_ReturnData
                    Return BK_return.BK_OK
                Else
                    Dim Except As New USB_exceptions(f_ReturnStatus)
                End If
            Else
                ' Out of sync, try dropping some bytes and finding the header
                For i = 0 To 4
                    If f_ReturnData(i) = &HAA AndAlso f_ReturnData(i + 1) = &HA5 Then

                    End If
                Next
                Dim Except As New Comm_Exceptions(Comm.Comm_Frame.BikiFrameResponse.SYNC_FAILED)
            End If
        Else
            Dim Except As New USB_exceptions(f_ReturnStatus)
        End If
    End Function
    Friend Sub BikiRom_Flush()
        FT_Purge(lngHandle, FT_Purg.FT_PURGE_TX + FT_Purg.FT_PURGE_RX)
    End Sub
    Friend Function BikiRom_read(ByVal ReturnLen As Integer) As Byte()
        Dim return_(ReturnLen - 1) As Byte
        Dim f_retCount As Integer = ReturnLen
        Dim flTimedout As Boolean = False
        Dim flFatalError As Boolean = False
        Dim lngTotalBytesRead As Integer = 0
        Dim ftStatus As Short
        Dim lngBytesRead As Integer = 0
        Dim byteArray(258) As Byte
        Dim arrayCursor As Short = 0
        Dim i As Short
        Dim f_count As Integer = 0
        If ReturnLen <> 0 Then
            flTimedout = False
            flFatalError = False

            '******************
            '** Wait for number of bytes code
            lngTotalBytesRead = 0
            Do
                lngBytesRead = 0
                ftStatus = FT_Read_Bytes(lngHandle, byteArray(0), f_retCount, lngBytesRead)
                'Debug.Print("FT_Read - send# :" & f_retCount & " Read: " & lngTotalBytesRead)
                If (ftStatus = FT_return.FT_OK) Or (ftStatus = FT_return.FT_IO_ERROR) Then
                    If lngBytesRead > 0 Then
                        For i = 1 To lngBytesRead
                            return_(arrayCursor) = byteArray(i - 1)
                            arrayCursor += 1
                        Next
                        lngTotalBytesRead += lngBytesRead
                        f_retCount -= lngBytesRead
                    Else

                        flTimedout = True
                    End If
                Else
                    flFatalError = True
                End If
            Loop Until (lngTotalBytesRead >= ReturnLen) Or (flTimedout = True) Or (flFatalError = True)
        Else
            FT_Purge(lngHandle, FT_Purg.FT_PURGE_RX)
        End If
        '*******************
        '** Return Code
        'Debug.Print("timeout: " & flTimedout & " Ioerror: " & flFatalError)
        Return return_
    End Function

    ''' <summary>
    ''' Functions below read data from the USB FT232's EEPROM space and write to it in a quick and easy fassion
    ''' </summary>
    ''' <remarks>These functions Assume that you already have a USB connection to the device</remarks>
    Friend Function GetUsbVariable(ByVal var As Biki_USBvars, ByRef oShort As UInt16) As Boolean
        Dim f_size As Integer
        If FT_EE_UASize(lngHandle, f_size) = FT_return.FT_OK Then
            If var + 1 >= f_size Then Return False : Exit Function
            Dim f_bytes(f_size - 1) As Byte
            Dim f_read As Integer
            If FT_EE_UARead(lngHandle, f_bytes, f_size, f_read) = FT_return.FT_OK Then
                oShort = MAKEWORD(f_bytes(var + 1), f_bytes(var))
                Return True
            Else : Return False
            End If
        Else : Return False
        End If
    End Function
    Friend Function GetUsbVariable(ByVal var As Biki_USBvars, ByRef oByte As Byte) As Boolean
        Dim f_size As Integer
        If FT_EE_UASize(lngHandle, f_size) = FT_return.FT_OK Then
            If var + 1 >= f_size Then Return False : Exit Function
            Dim f_bytes(f_size - 1) As Byte
            Dim f_read As Integer
            If FT_EE_UARead(lngHandle, f_bytes, f_size, f_read) = FT_return.FT_OK Then
                oByte = f_bytes(var)
                Return True
            Else : Return False
            End If
        Else : Return False
        End If
    End Function
    Friend Function GetUsbVariable(ByVal var As Biki_USBvars, ByRef oIntValue As UInt32) As Boolean
        Dim f_size As Integer
        If FT_EE_UASize(lngHandle, f_size) = FT_return.FT_OK Then
            If var + 1 >= f_size Then Return False : Exit Function
            Dim f_bytes(f_size - 1) As Byte
            Dim f_read As Integer
            If FT_EE_UARead(lngHandle, f_bytes, f_size, f_read) = FT_return.FT_OK Then
                Select Case var
                    Case Biki_USBvars.UV_Baud
                        oIntValue = MAKEWORD(f_bytes(var + 1), f_bytes(var))
                    Case Biki_USBvars.UV_EcuFLASH_CRC To Biki_USBvars.UV_EcuFLASH_CRC_MAP_3, Biki_USBvars.UV_BikPROG
                        oIntValue = makeLong(f_bytes(var), f_bytes(var + 1), f_bytes(var + 2), f_bytes(var + 3))
                End Select
                Return True
            Else : Return False
            End If
        Else : Return False
        End If
    End Function
    Friend Function SetUsbVariable(ByVal var As Biki_USBvars, ByVal sIntValue As UInt32) As Boolean
        Dim f_size As Integer
        If FT_EE_UASize(lngHandle, f_size) = FT_return.FT_OK Then
            If var + 1 >= f_size Then Return False : Exit Function
            Dim f_bytes(25) As Byte
            Dim f_read As Integer
            If FT_EE_UARead(lngHandle, f_bytes, f_size, f_read) = FT_return.FT_OK Then
                Select Case var
                    Case Biki_USBvars.UV_FirmWare
                        f_bytes(var) = sIntValue And &HFF
                    Case Biki_USBvars.UV_Baud
                        f_bytes(var + 1) = LOBYTE(sIntValue)
                        f_bytes(var) = HIBYTE(sIntValue)
                    Case Biki_USBvars.UV_EcuFLASH_CRC To Biki_USBvars.UV_EcuFLASH_CRC_MAP_3, Biki_USBvars.UV_BikPROG
                        f_bytes(var) = HIBYTE(hiInt(sIntValue))
                        f_bytes(var + 1) = LOBYTE(hiInt(sIntValue))
                        f_bytes(var + 2) = HIBYTE(loInt(sIntValue))
                        f_bytes(var + 3) = LOBYTE(loInt(sIntValue))
                End Select
                If FT_EE_UAWrite(lngHandle, f_bytes, f_size) = FT_return.FT_OK Then Return True Else Return False
            Else : Return False
            End If
        Else : Return False
        End If
    End Function

    Private Function inv(ByRef byte_ As Byte) As Byte
        inv = 0
        Dim m_loop As Byte

        For m_loop = 0 To 7
            If BitIsSet_byte(byte_, m_loop) Then
                inv = BitSet_byte(inv, 7 - m_loop)
            End If
        Next
    End Function

    Friend Sub close_bikirom()
        If Not IsNothing(m_UsbRxThread) Then
            If m_UsbRxThread.IsAlive Then m_UsbRxThread.Abort()
        End If
        m_BikiInfo.Initialised = False
        FT_Close(lngHandle)
        lngHandle = 0
    End Sub
    Friend Function Crc_byte(ByRef first_ As Byte, ByRef second_ As Byte) As Byte
        If first_ = second_ Then
            Crc_byte = 0
        Else
            Crc_byte = first_ Xor second_
        End If
    End Function
    Private Function byte_String(ByRef byte_ As Byte) As String
        If byte_ <= 15 Then
            byte_String = "0" & Mid(Hex(byte_), 2, 1)
        Else
            byte_String = Hex(byte_)
        End If
    End Function
    Friend Function BikiRom_UploadSector(ByVal sector As Byte, ByRef b_array() As Byte) As Boolean
        Dim i As Object
        Dim cmd() As Byte = Nothing
        Dim ret(512) As Byte
        Dim m_cursor As Double
        Dim s_crc As Double
        Dim s_data(512) As Byte
        Dim s_error As Byte
        Dim s_init() As Byte = {0}

        If lngHandle <> 0 And sector >= 0 And sector <= 3 Then

            ' Setup the Upload and start command
            Select Case sector
                Case 0
                    cmd = cv_BytesFromHex("CC3100AF0000")
                    Err_message(cv_StrFromBytes(cmd))
                    Err_message("sector 1")
                Case 1
                    cmd = cv_BytesFromHex("CC3100AF7FFF")
                    Err_message(cv_StrFromBytes(cmd))
                    Err_message("sector 2")
                Case 2
                    cmd = cv_BytesFromHex("CC3101AF0000")
                    Err_message(cv_StrFromBytes(cmd))
                    Err_message("sector 3")
                Case 3
                    cmd = cv_BytesFromHex("CC3101AF7FFF")
                    Err_message("sector 4")
                    Err_message(cv_StrFromBytes(cmd))
            End Select
            ' Erase Sector First
            'If Not BikiRom_EraseSector(sector) Then
            ' BikiRom_UploadSector = False
            ' Err_message("erase not ok")
            ' Exit Function
            'End If


            BikiRom_ReInit()
            ' Send command
            If BikiRom_sendCmdd(cmd, ret, 6, 2) = True Then
                If ret(1) = 170 Then
                    BikiRom_UploadSector = True
                Else
                    BikiRom_UploadSector = False
                    Err_message("return not correct")
                    Exit Function
                End If
            Else
                BikiRom_UploadSector = False
                Err_message("timout")
                Exit Function
            End If

            ' Upload Data
            s_data(0) = 223
            For m_cursor = 0 To 65535 Step g_packetSize

                ' Copy and Calculate Crc byte
                s_crc = 0
                array_copy(b_array, m_cursor, s_data, 1, g_packetSize)
                For i = 1 To g_packetSize
                    s_crc = s_crc + CByte(s_data(i))
                Next
                s_data(g_packetSize + 1) = LOBYTE(s_crc)
reSend:
                ' Send Data packet
                If BikiRom_sendCmdd(s_data, ret, g_packetSize + 2, 1) = False Then
                    Err_message("error sending data paccket")
                    BikiRom_UploadSector = False
                    Exit Function
                Else
                    If ret(0) <> 223 Then
                        'System.Diagnostics.Debug.WriteLine("adr: " & Hex(m_cursor) & " " & cv_HexFromBytes(s_data) & " " & cv_HexFromBytes(ret) & " " & Hex(s_crc) & " " & Hex(s_data(257)))
                        s_error = s_error + 1
                        If s_error >= 100 Then
                            BikiRom_UploadSector = False
                            Err_message("lots of errors")
                            Exit Function
                        End If
                        GoTo reSend
                    End If
                End If

                ' Calculate Progress
                If (m_cursor Mod 1024) = 0 Then
                    StatusPercent(((m_cursor / 65536) * 100))
                End If
            Next

            ' Send End Marker Packet
            'UPGRADE_WARNING: Couldn't resolve default property of object cv_BytesFromHex(). Click for more: 'ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?keyword="6A50421D-15FE-4896-8A1B-2EC21E9037B2"'
            cmd = cv_BytesFromHex("FF")
            If BikiRom_sendCmdd(cmd, ret, 1, 1) Then
                StatusPercent((100))
                Return True
            Else
                Return False
            End If
        Else
            Return False
        End If
    End Function
    Friend Sub BikiRom_SetTimeoutHigh(ByVal bool As Boolean)
        If bool Then
            FT_SetTimeouts(lngHandle, 10000, 0)
        Else
            FT_SetTimeouts(lngHandle, 100, 0)
        End If
    End Sub
    Friend Sub BikiRom_SetTimeout(ByVal TimeOut As Integer)
        If lngHandle <> 0 Then
            FT_SetTimeouts(lngHandle, TimeOut, TimeOut)
        End If
    End Sub

    Friend Sub BikiRom_Timeout(ByVal time As Integer)
        m_BikiInfo.TimeOut = time
    End Sub

    ' This function Takes 0-4 and erases that sector or entire flash for mode 4
    Friend Function BikiRom_EraseSector(ByVal sector As BikiAction) As BK_return
        Dim f_Frame As Comm.Comm_Frame
        m_BikiInfo.TimeOut = 8000
        Try
            Select Case sector
                Case BikiAction.BK_MAP1
                    f_Frame = New Comm.Comm_Frame(Comm.Comm_Frame.BikiFrameType.ID_RUN_COMMAND, &H0, Comm.Comm_Frame.BikiFrameAction.RUN_ERASESECTOR)
                    f_Frame.Send()
                Case BikiAction.BK_MAP2
                    f_Frame = New Comm.Comm_Frame(Comm.Comm_Frame.BikiFrameType.ID_RUN_COMMAND, &H10000, Comm.Comm_Frame.BikiFrameAction.RUN_ERASESECTOR)
                    f_Frame.Send()
                Case BikiAction.BK_MAP3
                    f_Frame = New Comm.Comm_Frame(Comm.Comm_Frame.BikiFrameType.ID_RUN_COMMAND, &H20000, Comm.Comm_Frame.BikiFrameAction.RUN_ERASESECTOR)
                    f_Frame.Send()
                Case BikiAction.BK_CFG
                    f_Frame = New Comm.Comm_Frame(Comm.Comm_Frame.BikiFrameType.ID_RUN_COMMAND, &H30000, Comm.Comm_Frame.BikiFrameAction.RUN_ERASESECTOR)
                    f_Frame.Send()
                    f_Frame = New Comm.Comm_Frame(Comm.Comm_Frame.BikiFrameType.ID_RUN_COMMAND, &H38000, Comm.Comm_Frame.BikiFrameAction.RUN_ERASESECTOR)
                    f_Frame.Send()
                    f_Frame = New Comm.Comm_Frame(Comm.Comm_Frame.BikiFrameType.ID_RUN_COMMAND, &H3A000, Comm.Comm_Frame.BikiFrameAction.RUN_ERASESECTOR)
                    f_Frame.Send()
                    f_Frame = New Comm.Comm_Frame(Comm.Comm_Frame.BikiFrameType.ID_RUN_COMMAND, &H3C000, Comm.Comm_Frame.BikiFrameAction.RUN_ERASESECTOR)
                    f_Frame.Send()
                Case BikiAction.BK_ALL
                    f_Frame = New Comm.Comm_Frame(Comm.Comm_Frame.BikiFrameType.ID_RUN_COMMAND, &H3C000, Comm.Comm_Frame.BikiFrameAction.RUN_ERASEALL)
                    f_Frame.Send()
            End Select
        Catch exComm As Comm_Exceptions
            m_BikiInfo.reset()
            Return BK_return.BK_IO_ERROR_BIK
        Catch exUsb As USB_exceptions
            m_BikiInfo.reset()
            Return BK_return.BK_IO_ERROR_USB
        End Try
        m_BikiInfo.TimeOut = 500
        Return BK_return.BK_OK
    End Function

    '    Friend Function BikiRom_EraseSector(ByVal sector As Integer) As Boolean
    '        Dim cmd() As Byte
    '        Dim s_init() As Byte = {0}
    '        Dim ret(10) As Byte

    '        If lngHandle <> 0 And sector >= 0 And sector <= 4 Then
    '            BikiRom_SetTimeoutHigh(True)
    '            Select Case sector
    '                Case BikiAction.BK_MAP1
    '                    cmd = cv_BytesFromHex("CC3400AF0000")
    '                    GoTo singleCmd
    '                Case BikiAction.BK_MAP2
    '                    cmd = cv_BytesFromHex("CC3400AF8000")
    '                    GoTo singleCmd
    '                Case BikiAction.BK_MAP3
    '                    cmd = cv_BytesFromHex("CC3401AF0000")
    '                    GoTo singleCmd
    '                Case BikiAction.BK_CFG
    '                    cmd = cv_BytesFromHex("CC3401AF8000")
    '                    If BikiRom_sendCmdd(cmd, ret, 6, 2) = True Then
    '                        If ret(1) = 170 Then
    '                            BikiRom_EraseSector = True
    '                        Else
    '                            BikiRom_EraseSector = False
    '                            Exit Function
    '                        End If
    '                    Else
    '                        BikiRom_EraseSector = False
    '                        Exit Function
    '                    End If
    '                    cmd = cv_BytesFromHex("CC3401AFC000")
    '                    If BikiRom_sendCmdd(cmd, ret, 6, 2) = True Then
    '                        If ret(1) = 170 Then
    '                            BikiRom_EraseSector = True
    '                        Else
    '                            BikiRom_EraseSector = False
    '                            Exit Function
    '                        End If
    '                    Else
    '                        BikiRom_EraseSector = False
    '                        Exit Function
    '                    End If
    '                    cmd = cv_BytesFromHex("CC3401AFD000")
    '                    BikiRom_sendCmdd(s_init, ret, 1, 0)
    '                    System.Threading.Thread.Sleep(20)

    '                    If BikiRom_sendCmdd(cmd, ret, 6, 2) = True Then
    '                        If ret(1) = 170 Then
    '                            BikiRom_EraseSector = True
    '                        Else
    '                            BikiRom_EraseSector = False
    '                            Exit Function
    '                        End If
    '                    Else
    '                        BikiRom_EraseSector = False
    '                        Exit Function
    '                    End If
    '                    cmd = cv_BytesFromHex("CC3401AFE000")
    '                    BikiRom_sendCmdd(s_init, ret, 1, 0)
    '                    System.Threading.Thread.Sleep(20)

    '                    If BikiRom_sendCmdd(cmd, ret, 6, 2) = True Then
    '                        If ret(1) = 170 Then
    '                            BikiRom_EraseSector = True
    '                        Else
    '                            BikiRom_EraseSector = False
    '                            Exit Function
    '                        End If
    '                    Else
    '                        BikiRom_EraseSector = False
    '                        Exit Function
    '                    End If
    '                Case BikiAction.BK_ALL
    '                    cmd = cv_BytesFromHex("CC3300")
    '                    If BikiRom_sendCmdd(cmd, ret, 3, 1) = True Then
    '                        If ret(0) = 170 Then
    '                            BikiRom_EraseSector = True
    '                        Else
    '                            BikiRom_EraseSector = False
    '                        End If
    '                    Else
    '                        BikiRom_EraseSector = False
    '                    End If
    '            End Select
    '        End If
    '        BikiRom_SetTimeoutHigh(False)
    '        Exit Function
    'singleCmd:
    '        If BikiRom_sendCmdd(cmd, ret, 6, 2) = True Then
    '            If ret(2) = 170 Then
    '                BikiRom_EraseSector = True
    '            Else
    '                BikiRom_EraseSector = False
    '            End If
    '        Else
    '            BikiRom_EraseSector = False
    '        End If
    '        BikiRom_SetTimeoutHigh(False)
    '    End Function
    Friend Function BikiRom_DownloadSector(ByVal sector As Byte, ByRef b_array() As Byte) As Boolean
        Dim e As Object
        Dim s_crc, m_loop As Double
        Dim cmd() As Byte = Nothing
        Dim s_error As Byte
        Dim ret(512) As Byte

        If lngHandle <> 0 And sector >= 0 And sector <= 3 Then
            ' Setup the download and start command
            Select Case sector
                Case 0
                    'UPGRADE_WARNING: Couldn't resolve default property of object cv_BytesFromHex(). Click for more: 'ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?keyword="6A50421D-15FE-4896-8A1B-2EC21E9037B2"'
                    cmd = cv_BytesFromHex("CC3200AF0000")
                Case 1
                    'UPGRADE_WARNING: Couldn't resolve default property of object cv_BytesFromHex(). Click for more: 'ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?keyword="6A50421D-15FE-4896-8A1B-2EC21E9037B2"'
                    cmd = cv_BytesFromHex("CC3200AF8000")
                Case 2
                    'UPGRADE_WARNING: Couldn't resolve default property of object cv_BytesFromHex(). Click for more: 'ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?keyword="6A50421D-15FE-4896-8A1B-2EC21E9037B2"'
                    cmd = cv_BytesFromHex("CC3201AF0000")
                Case 3
                    'UPGRADE_WARNING: Couldn't resolve default property of object cv_BytesFromHex(). Click for more: 'ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?keyword="6A50421D-15FE-4896-8A1B-2EC21E9037B2"'
                    cmd = cv_BytesFromHex("CC3201AF7FFF")
            End Select

            BikiRom_ReInit()

            ' Send command
            If BikiRom_sendCmdd(cmd, ret, 6, 2) = True Then
                If ret(1) = 170 Then
                    BikiRom_DownloadSector = True
                Else
                    BikiRom_DownloadSector = False
                    Exit Function
                End If
            Else
                BikiRom_DownloadSector = False
                Exit Function
            End If

            ' Download Data
            'UPGRADE_WARNING: Couldn't resolve default property of object cv_BytesFromHex(). Click for more: 'ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?keyword="6A50421D-15FE-4896-8A1B-2EC21E9037B2"'
            cmd = cv_BytesFromHex("DF")
            For m_loop = 0 To 65536 - g_packetSize Step g_packetSize
repeat:
                ' Send download Command
                If Not BikiRom_sendCmdd(cmd, ret, 1, g_packetSize + 2) Then
                    BikiRom_DownloadSector = False
                    Exit Function
                End If

                ' Calculate CRC
                s_crc = 0
                For e = 1 To g_packetSize
                    'UPGRADE_WARNING: Couldn't resolve default property of object e. Click for more: 'ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?keyword="6A50421D-15FE-4896-8A1B-2EC21E9037B2"'
                    s_crc = s_crc + ret(e)
                Next

                ' Check CRC and copy data
                If LOBYTE(s_crc) <> ret(g_packetSize + 1) Then
                    s_error = s_error + 1
                    If s_error > 100 Then
                        BikiRom_DownloadSector = False
                        Exit Function
                    End If
                    GoTo repeat
                Else
                    array_copy(ret, 1, b_array, m_loop, g_packetSize)
                End If
                'UPGRADE_WARNING: Mod has a new behavior. Click for more: 'ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?keyword="9B7D5ADD-D8FE-4819-A36C-6DEDAF088CC7"'
                If m_loop Mod 1024 = 0 Then
                    StatusPercent(((m_loop / 65536) * 100)) ' m_fileLength) * 100
                End If
            Next
            BikiRom_DownloadSector = True
        End If
    End Function
    ''' <summary>
    ''' Uploads an array given the mode change command in modeStr
    ''' </summary>
    ''' <param name="modeStr">Mode Change String</param>
    ''' <param name="data">Array to upload</param>
    ''' <param name="Packets">Number of 256byte packets to upload</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Friend Function BikiRom_UploadWcmd(ByVal modeStr As String, ByRef data() As Byte, ByVal Packets As Byte) As BK_return
        ' Upload Data
        Dim f_return As BK_return
        Dim ret(16) As Byte
        Dim s_data(257) As Byte
        Dim s_crc As Long
        Dim s_error As Int16
        s_data(0) = 223
        If Not IsNothing(data) And Packets >= 1 And UBound(data) >= (Packets * 256) - 1 Then
            f_return = BikiRom_Init()
            If f_return = BK_return.BK_OK Then
                BikiRom_SetTimeout(4000)
                If BikiRom_HexCmdAA(modeStr) Then
                    For m_cursor As Integer = 0 To (Packets - 1)
                        s_crc = 0
                        array_copy(data, m_cursor * 256, s_data, 1, g_packetSize)
                        For i As Integer = 1 To 256
                            s_crc += CByte(s_data(i))
                        Next
                        s_data(257) = LOBYTE(s_crc)
reSend:
                        ' Send Data packet
                        If BikiRom_sendCmdd(s_data, ret, g_packetSize + 2, 1) = False Then
                            Debug.Print("Packet NO RETURN")
                            Return BK_return.BK_IO_ERROR_BIK
                            GoTo close
                        Else
                            If ret(0) <> &HDF Then
                                Debug.Print("Packet return NOT OK")
                                s_error += 1
                                If s_error >= 10 Then Return BK_return.BK_IO_ERROR_BIK : GoTo close
                                GoTo reSend
                            End If
                        End If
                    Next
                    If BikiRom_hexCmd("FF") Then Return BK_return.BK_OK Else Return BK_return.BK_FAILED_CMD
close:
                Else
                    Debug.Print("mode change not ok")
                End If
            Else : Return f_return
            End If
        Else : Return BK_return.BK_ERROR_CATCH
        End If
    End Function
    Friend Function BikiRom_DownloadWcmd(ByVal modeChange As String, ByVal Packets As Short) As Byte()
        Dim f_return() As Byte = Nothing
        If BikiRom_Init() = BK_return.BK_OK Then
            BikiRom_SetTimeout(4000)
            If BikiRom_HexCmdAA(modeChange) Then
                ReDim f_return((Packets * 256) - 1)
                Dim ret(260) As Byte
                Dim s_crc As Long
                Dim s_error As Int16 = 0

                For m_loop As Integer = 0 To Packets - 1
repeat:
                    ' Send download Command --------------------------------------------------------------------------------
                    If Not BikiRom_hexCmd("DF", ret, 258) Then f_return = Nothing : GoTo close

                    ' Calculate CRC ----------------------------------------------------------------------------------------
                    s_crc = 0 : For crc As Int32 = 1 To 256 : s_crc += ret(crc) : Next

                    ' Check CRC and copy data ------------------------------------------------------------------------------
                    If LOBYTE(s_crc) <> ret(257) Then : s_error += 1 : If s_error > 10 Then f_return = Nothing : GoTo close
                    Else
                        array_copy(ret, 1, f_return, m_loop * 256, 256)
                    End If
                Next
            Else : f_return = Nothing
            End If
        Else : f_return = Nothing
        End If
close:
        Return f_return
    End Function
    Friend Sub BikiRom_Reset()
        FT_ClrRts(lngHandle)
        Threading.Thread.Sleep(20)
        FT_SetDtr(lngHandle)
        Threading.Thread.Sleep(20)
        FT_ClrDtr(lngHandle)
        Threading.Thread.Sleep(100)
    End Sub
    Friend Function BikiRom_ReInit() As Boolean
        Dim s_init() As Byte = {0}
        Dim ret(3) As Byte
        Dim s_try As Byte = 1
retry:
        BikiRom_Reset()
        System.Threading.Thread.Sleep(600 * s_try)
        BikiRom_Flush()
        If BikiRom_HexCmdAA("00") Then
            Return True
        Else
            If s_try <= 3 Then
                s_try += 1
                GoTo retry
            Else
                Return False
            End If
        End If
    End Function
    Friend Sub BikiRom_BootMode()
        FT_SetRts(lngHandle)
        Threading.Thread.Sleep(20)
        FT_SetDtr(lngHandle)
        Threading.Thread.Sleep(20)
        FT_ClrDtr(lngHandle)
        Threading.Thread.Sleep(20)
    End Sub
    Friend Function consult_mode() As Boolean
        Dim f_consultMode() As Byte = cv_BytesFromHex("CC8100")
        Dim f_consultInit() As Byte = cv_BytesFromHex("FFFFEF")
        Dim f_return(30) As Byte
        If BikiRom_Init() Then
            Threading.Thread.Sleep(50)
            'BikiRom_SetTimeoutHigh(True)
            If BikiRom_sendCmdd(f_consultMode, f_return, 3, 1) Then
                If f_return(0) = 170 Then
                    If BikiRom_sendCmdd(f_consultInit, f_return, 3, 1) Then
                        If f_return(0) <> 16 And f_return(0) <> 0 Then
                            Console.WriteLine("Error from init commmand")
                            Return Nothing
                            Exit Function
                        End If
                    End If
                Else
                    Console.WriteLine("error sending init command")
                    Return Nothing
                    Exit Function
                End If
            Else
                Return Nothing
                Console.WriteLine("Error on return value from consult mode")
                Exit Function
            End If
            Return True
        Else
            Return False
        End If
    End Function
    Friend Function Consult_Download(ByRef address As Integer, ByRef length As Integer, ByRef f_array() As Byte, Optional ByRef callBack As ProgressBar = Nothing) As BK_return
        Dim f_return(256) As Byte
        ReDim f_array(length - 1)
        Dim f_consultInit() As Byte = cv_BytesFromHex("FFFFEF")

        ' Inital command
        Dim f_cmd() As Byte = cv_BytesFromHex("C90000C90000C90000C90000F0")
        Dim f_stop() As Byte = cv_BytesFromHex("30")
        Dim f_error As Integer = 0
        Dim f_stream(0 To 120) As Byte
        Dim f_filter() As Byte
        Dim fnum As Integer = FreeFile()
        Dim i As Integer = 0
        'BikiRom_SetTimeoutHigh(True)
        ' Formulate command and prepare to send
        m_BikiInfo.TimeOut = 500

        BikiRom_hexCmd("30FFFFEF", 3)

        For i = address To address + length - 4 Step 4
            Application.DoEvents()
            FT_Purge(lngHandle, FT_Purg.FT_PURGE_RX)
retry:
            Console.WriteLine("at adr: " & Hex(i))
            ' f_error = 0
            Threading.Thread.Sleep(10)
            For s As Integer = 0 To 3
                f_cmd((s * 3) + 1) = HIBYTE(s + i)
                f_cmd((s * 3) + 2) = LOBYTE(s + i)
            Next
            For Each by As Byte In f_stream
                by = 0
            Next
            If BikiRom_sendCmdd(f_cmd, f_stream, 13, 30) Then
                Debug.Print("Inside the F0 wait!")
                BikiRom_hexCmd("30")
                f_filter = consult_Filter(f_stream, 4)
                If Not IsNothing(f_filter) Then
                    array_copy(f_filter, 0, f_array, i - address, 4)

                    Debug.Print("packet filtered ok")
                    f_error = 0
                    If Not IsNothing(callBack) Then
                        callBack.Value = ((i - address) / (length)) * 100
                    End If
                Else
                    BikiRom_hexCmd("30")
                    f_error += 1

                    Console.WriteLine("Error in sync at: " & Hex(i))
                    If f_error >= 20 Then
                        Console.WriteLine("Alot of errors at: " & Hex(i))
                        If MsgBox("Error Encountered. Press Retry to try again", MsgBoxStyle.RetryCancel + MsgBoxStyle.Question, "Error. Retry?") = MsgBoxResult.Retry Then
                            BikiRom_hexCmd("30FFFFEF")
                            f_error = 0
                            GoTo retry
                        Else
                            address = i
                            Return BK_return.BK_CONSULT_FAILED
                        End If
                    End If
                    Threading.Thread.Sleep(5)
                    FT_Purge(lngHandle, FT_Purg.FT_PURGE_RX)
                    GoTo retry
                End If
            Else
                If f_error >= 20 Then
                    If MsgBox("Error Encountered. Press Retry to try again", MsgBoxStyle.RetryCancel + MsgBoxStyle.Question, "Error. Retry?") = MsgBoxResult.Retry Then
                        BikiRom_hexCmd("30FFFFEF")
                        f_error = 0
                        GoTo retry
                    Else
                        address = i
                        Return BK_return.BK_IO_ERROR_BIK
                    End If
                End If
                f_error += 1
                GoTo retry
            End If
        Next
        address = i
        Return BK_return.BK_OK
    End Function
    '    Friend Function Consult_Download(ByRef Car_ As Car) As Boolean
    '        Dim f_return(256) As Byte
    '        Dim f_array(0 To 65535) As Byte
    '        Dim f_consultMode() As Byte = cv_BytesFromHex("CC8100")
    '        Dim f_consultInit() As Byte = cv_BytesFromHex("FFFFEF")
    '        If BikiRom_Init() Then
    '            Threading.Thread.Sleep(50)
    '            BikiRom_SetTimeoutHigh(True)
    '            If BikiRom_sendCmdd(f_consultMode, f_return, 3, 1) Then
    '                If f_return(0) = 170 Then
    '                    If BikiRom_sendCmdd(f_consultInit, f_return, 3, 1) Then
    '                        If f_return(0) <> 16 And f_return(0) <> 0 Then
    '                            Console.WriteLine("Error from init commmand")
    '                            Exit Function
    '                        End If
    '                    End If
    '                Else
    '                    Console.WriteLine("error sending init command")
    '                    Exit Function
    '                End If
    '            Else
    '                Console.WriteLine("Error on return value from consult mode")
    '                Exit Function
    '            End If


    '            ' Inital command
    '            Dim f_cmd() As Byte = cv_BytesFromHex("C90000C90000C90000C90000F0")
    '            Dim f_stop() As Byte = cv_BytesFromHex("30")
    '            Dim f_enter() As Byte = cv_BytesFromHex("00")
    '            Dim f_reinit() As Byte = cv_BytesFromHex("CC8100")
    '            Dim f_error As Integer = 0
    '            Dim f_stream(0 To 120) As Byte
    '            Dim f_filter() As Byte
    '            Dim fnum As Integer = FreeFile()
    '            BikiRom_SetTimeoutHigh(True)
    '            ' Formulate command and prepare to send

    '            For i As Integer = Car_.getDataStart To Car_.getDataEnd Step 4
    'retry:
    '                Console.WriteLine("at adr: " & Hex(i))
    '                f_error = 0
    '                Threading.Thread.Sleep(10)
    '                For s As Integer = 0 To 3
    '                    f_cmd((s * 3) + 1) = HIBYTE(s + i)
    '                    f_cmd((s * 3) + 2) = LOBYTE(s + i)
    '                Next
    '                For Each by As Byte In f_stream
    '                    by = 0
    '                Next
    '                If BikiRom_sendCmdd(f_cmd, f_stream, 13, 30) Then
    '                    Debug.Print("Inside the F0 wait!")
    '                    BikiRom_hexCmd("30")
    '                    f_filter = consult_Filter(f_stream, 4)
    '                    If Not IsNothing(f_filter) Then
    '                        array_copy(f_filter, 0, f_array, i, 4)
    '                        'FilePut(fnum, f_filter, i + 1)
    '                        Debug.Print("packet filtered ok")
    '                    Else
    '                        f_error += 1
    '                        debug_dump_array(f_return, 0, 32)
    '                        Console.WriteLine("Error in sync at: " & Hex(i))
    '                        If f_error >= 5 Then
    '                            Console.WriteLine("Alot of errors at: " & Hex(i))
    '                            Exit Function
    '                        End If
    '                        Threading.Thread.Sleep(5)
    '                        FT_Purge(lngHandle, FT_Purg.FT_PURGE_RX)
    '                        GoTo retry
    '                    End If
    '                Else
    '                    Console.WriteLine("Error sending Bytes")
    '                    BikiRom_ReInit()
    '                    Threading.Thread.Sleep(10)
    '                    BikiRom_sendCmdd(f_reinit, f_return, 3, 1)
    '                    Threading.Thread.Sleep(5)
    '                    If BikiRom_sendCmdd(f_consultInit, f_return, 3, 1) Then
    '                        If f_return(0) = 16 Or f_return(0) = 0 Then
    '                            Console.WriteLine("Re-init consult OK")
    '                        Else
    '                            Console.WriteLine("Re-init consult Not OK")
    '                        End If
    '                    Else
    '                        Console.WriteLine("Re-init consult NOT OK")
    '                    End If
    '                    If f_error >= 5 Then Exit Function
    '                    f_error += 1
    '                    GoTo retry
    '                End If
    '                StatusPercent(((i - Car_.getDataStart) / (Car_.getDataEnd - Car_.getDataStart)) * 100)
    '            Next
    '            Dim f_serial As String = ""
    '            If BikiRom_hexCmd("D0F0", f_stream, 100) Then
    '                f_filter = consult_Filter(f_stream, 22)
    '                f_serial = Chr(f_stream(17)) & Chr(f_stream(18)) & Chr(f_stream(19)) & Chr(f_stream(20)) & Chr(f_stream(21))
    '            End If
    '            BikiRom_hexCmd("30")

    '            If f_serial <> "" Then
    '                Try
    '                    Dim f_FileStream As New FileStream(Application.StartupPath & "\Base Data\" & f_serial, FileMode.CreateNew)
    '                    Dim f_BinWriter As New BinaryWriter(f_FileStream)
    '                    f_BinWriter.Write(f_array)
    '                Catch
    '                Finally
    '                End Try
    '            End If

    '            Car_.baseImport(f_array)
    '            Return True
    '            BikiRom_SetTimeoutHigh(False)
    '        Else
    '            Return False
    '        End If
    '    End Function
    Friend Function consult_Filter(ByRef Stream_() As Byte, ByVal Size_ As Byte) As Byte()
        Dim f_return(0 To Size_ - 1) As Byte
        Dim found As Boolean = False
        Dim i As Integer
        If Stream_.Length >= Size_ + 2 Then
            For i = 0 To UBound(Stream_) - Size_ - 4
                If Stream_(i) = 255 And Stream_(i + 1) = Size_ And Stream_(i + 2 + Size_) = 255 And Stream_(i + 3 + Size_) = Size_ Then
                    found = True
                    Exit For
                End If
            Next
            If found Then
                array_copy(Stream_, i + 2, f_return, 0, Size_)
                Return f_return
            Else
                Return Nothing
            End If
        Else
            Return Nothing
        End If
    End Function
End Module

Friend Class Comm_RxHandle
    ' Global status variable for this class, determines which byte is currently being seeked out
    Private m_RxStatus As UInt16 = 0
    ' Global Bytes Excepted Variable.
    Private m_RxBytes As UInt16 = 0

    Private WithEvents m_usbRxTimer As New System.Timers.Timer(1)

    Sub rxthreadtimer(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs) Handles m_usbRxTimer.Elapsed
        m_UsbRxEvent.Set()
    End Sub

    Sub execute()
        Dim i As UInt64
        Dim f_Rcv() As Byte
        Dim f_Wait(0) As WaitHandle
        Dim f_confirm As Boolean = True
        f_Wait(0) = m_UsbRxEvent
        'f_Wait(1) = m_UsbTxEvent2

        m_usbRxTimer.Start()

        Do
            Threading.Thread.EndCriticalRegion()
            WaitHandle.WaitAll(f_Wait, -1, False)
            Threading.Thread.BeginCriticalRegion()
            m_UsbRxEvent2.Reset()
            ' m_UsbTxEvent2.Set()
            f_Rcv = usb_read()
            If Not IsNothing(f_Rcv) AndAlso f_Rcv.Length > 0 Then
                'Debug.WriteLine(f_Rcv.ToString)
                i = 0
                m_UsbRx.AddRange(f_Rcv)
retry:          If m_RxStatus = 0 And m_UsbRx.Count >= 4 Then
                    For i = 0 To m_UsbRx.Count - 4
                        If m_UsbRx(i) = &HAA And _
                         m_UsbRx(i + 1) = &HA5 And _
                         m_UsbRx(i + 2) = &H1A And _
                         (m_UsbRx(i + 3) = &H2A Or m_UsbRx(i + 3) = &HA Or m_UsbRx(i + 3) = &H70) _
                         Then
                            ' Headers Found!
                            m_RxStatus = 4
                            m_RxBytes = 0
                            If i > 0 Then
                                m_UsbRx.RemoveRange(0, i) ' clears out all the crap
                            End If
                            Exit For
                        End If
                    Next
                End If
                ' Header already in buffer and at begining, searching for the bytes
                If m_RxStatus = 4 Then
                    If m_UsbRx.Count >= 6 Then
                        m_RxBytes = (m_UsbRx(4) * &H100) Or m_UsbRx(5)
                        If m_RxBytes >= 2048 Then
                            m_RxStatus = 0
                            m_UsbRx.RemoveRange(0, 6)
                        Else
                            m_RxStatus = 6
                        End If
                    End If
                End If
                ' Headers and Bytes recieved, looking for final count in the stream now
                If m_RxStatus = 6 Then
                    If m_UsbRx.Count >= (m_RxBytes + 10) Then
                        ' Headers and everything is ready..
                        ' Check if the Footer exists
                        If m_UsbRx(m_RxBytes + 9) = &H5A And _
                           m_UsbRx(m_RxBytes + 8) = &H55 _
                        Then
                            Dim f_Data(m_RxBytes + 9) As Byte
                            m_UsbRx.CopyTo(0, f_Data, 0, m_RxBytes + 10)
                            Console.WriteLine("Read: " & cv_HexFromBytes(f_Data))
                            Dim f_Frame As New Comm.Comm_Frame(f_Data)
                            If f_Frame.IsValid Then
                                If m_UsbRx(3) = &H2A Or m_UsbRx(3) = &H70 Then
                                    Select Case CType(m_UsbRx(6), Comm.Comm_Frame.BikiFrameType)
                                        Case Comm.Comm_Frame.BikiFrameType.ID_CONSULT_INTEGRATED
                                            Queue.Synchronized(m_UsbConsultIntegratedBuffer).Enqueue(f_Frame)
                                            m_UsbStreamEvent.Set()
                                        Case Comm.Comm_Frame.BikiFrameType.ID_EEPROM_DATA
                                            Queue.Synchronized(m_UsbEEpromDataBuffer).Enqueue(f_Frame)
                                            m_UsbEEpromDataEvent.Set()
                                        Case Comm.Comm_Frame.BikiFrameType.ID_FLASH_DATA
                                            Queue.Synchronized(m_UsbFlashDataBuffer).Enqueue(f_Frame)
                                            m_UsbFlashDataEvent.Set()
                                        Case Comm.Comm_Frame.BikiFrameType.ID_LAST_COMMAND_STATUS
                                            Queue.Synchronized(m_UsbLastCmdStatusBuffer).Enqueue(f_Frame)
                                            m_UsbLastCmdStatusEvent.Set()
                                        Case Comm.Comm_Frame.BikiFrameType.ID_GENERAL_SPECIFIC
                                            Queue.Synchronized(m_UsbGeneralSpecificBuffer).Enqueue(f_Frame)
                                            m_UsbGeneralSpecificEvent.Set()
                                    End Select
                                ElseIf m_UsbRx(3) = &HA Then
                                    Dim f_consult() As Byte = Nothing

                                    ReDim f_consult(m_RxBytes - 1)
                                    Array.Copy(f_Data, 6, f_consult, 0, m_RxBytes)
                                    m_UsbConsultPassBuffer = f_consult
                                    m_UsbConsultEvent.Set()

                                End If
                                ' Get the Frames ID
                                m_UsbRx.RemoveRange(0, m_RxBytes + 10)
                                m_RxStatus = 0
                            Else ' CRC FAILED!
                                ' clear the frame header
                                m_UsbRx.RemoveRange(0, m_RxBytes + 10)
                                m_RxStatus = 0
                                m_UsbCRCFailedEvent.Set()
                            End If
                        Else ' Headers and Footers Failed
                            m_UsbRx.RemoveRange(0, m_RxBytes + 6)
                            m_RxStatus = 0
                            m_UsbHeadersFailedEvent.Set()
                            GoTo retry
                        End If
                    End If
                End If
            End If
            m_UsbRxEvent2.Set()
            If frameExists() Then GoTo retry
        Loop

        m_usbRxTimer.Stop()
    End Sub
    '' checks if a full frame exists in the buffer...
    Private Function frameExists() As Boolean
        Dim f_Bytes As UInt16
        If m_UsbRx.Count >= 6 AndAlso (m_UsbRx(0) = &HAA And _
               m_UsbRx(1) = &HA5) Then
            f_Bytes = (m_UsbRx(4) * &H100) Or m_UsbRx(5)
            If f_Bytes < m_BikiInfo.MaxRxPacket + 50 AndAlso _
               m_UsbRx.Count >= f_Bytes + 10 AndAlso _
               (m_UsbRx(f_Bytes + 9) = &H5A And _
               m_UsbRx(f_Bytes + 8) = &H55) Then
                Return True
            End If
        End If
        Return False
    End Function
End Class

Friend Class Comm_BikiInfo
    Public Enum FirmwareVersion As Byte
        FV_CHRIS = 0
        FV_LUCAS = 1
    End Enum

    Private m_Baud As ULong = 500000
    Private m_Clock As ULong = 16000000
    Private m_SerialNo As String = ""
    Private m_BoardNo As UInt32 = 0
    Private m_MaxRxPacket As UInteger = 186
    Private m_MaxTxPacket As UInteger = 1054
    Private m_FirmwareVersion As Byte = 0
    Private m_TimeOut As UInt16 = 500
    Private m_UserByte As Byte = &HFF
    Private m_SecByte As Byte = &HFF
    Private m_Init As Boolean = False

    Public Sub reset()
        m_TimeOut = 500
        m_MaxRxPacket = 186
        m_MaxTxPacket = 1054
        setUSBParameters()
        BikiRom_SetTimeout(500)
    End Sub

    Public Property Initialised() As Boolean
        Get
            Return m_Init
        End Get
        Set(ByVal value As Boolean)
            m_Init = value
        End Set
    End Property
    Public Property TimeOut() As UInt16
        Get
            Return m_TimeOut
        End Get
        Set(ByVal value As UInt16)
            m_TimeOut = value
            BikiRom_SetTimeout(value)
        End Set
    End Property
    Public Property Baud() As ULong
        Get
            Return m_Baud
        End Get
        Set(ByVal value As ULong)
            m_Baud = value
        End Set
    End Property
    Public Property Clock() As ULong
        Get
            Return m_Clock
        End Get
        Set(ByVal value As ULong)
            m_Clock = value
        End Set
    End Property
    Public Property SerialNo() As String
        Get
            Return m_SerialNo
        End Get
        Set(ByVal value As String)
            m_SerialNo = value
        End Set
    End Property
    Public Property MaxRxPacket() As UInteger
        Get
            'Return m_MaxRxPacket
            Return 186
        End Get
        Set(ByVal value As UInteger)
            'm_MaxRxPacket = value
            setUSBParameters()
        End Set
    End Property
    Public Property MaxTxPacket() As UInteger
        Get
            Return m_MaxTxPacket
        End Get
        Set(ByVal value As UInteger)
            m_MaxTxPacket = value
            setUSBParameters()
        End Set
    End Property
    Public Property FirmwareVer() As FirmwareVersion
        Get
            Return FirmwareVersion.FV_LUCAS
            Return m_FirmwareVersion
        End Get
        Set(ByVal value As FirmwareVersion)
            m_FirmwareVersion = value
        End Set
    End Property
    Public ReadOnly Property BoardNo() As UInt32
        Get
            Return m_BoardNo
        End Get
    End Property
    Public ReadOnly Property OsVersion() As Byte
        Get
            Return m_FirmwareVersion
        End Get
    End Property
    Public ReadOnly Property BaseEnabled() As Boolean
        Get
            If m_UserByte And &H1 Then
                Return False
            Else
                Return True
            End If
        End Get
    End Property
    Public ReadOnly Property BoostEnabled() As Boolean
        Get
            If m_UserByte And &H2 Then
                Return False
            Else
                Return True
            End If
        End Get
    End Property

    Public Function getBikiromInfo() As Boolean
        Dim f_frame As Comm.Comm_Frame
        Dim f_Packet() As Byte = Nothing
        Dim f_cnt As Integer = 0
        Try
            m_BikiInfo.TimeOut = 1000

            Thread.Sleep(100)

            f_frame = New Comm.Comm_Frame(Comm.Comm_Frame.BikiFrameType.ID_RUN_COMMAND, , Comm.Comm_Frame.BikiFrameAction.RUN_GET_INFO, , Comm.Comm_Frame.BikiFrameType.ID_GENERAL_SPECIFIC)
retry:      f_frame.Send(f_Packet, True, 2)

            If Not IsNothing(f_Packet) Then
                If f_Packet(0) = &HFF Then f_Packet(0) = 0
                m_BoardNo = (CULng(f_Packet(0)) << 16) + (CULng(f_Packet(1)) << 8) + (CULng(f_Packet(2)))
                m_Clock = CULng(f_Packet(5))
                m_UserByte = f_Packet(4)
                m_SecByte = f_Packet(3)
                m_FirmwareVersion = f_Packet(6)
                Console.WriteLine("MOD_BIKIUSB: Got BikiInfo OK try {0:G}", f_cnt)
            Else
                Console.WriteLine("MOD_BIKIUSB: Failing getting bikirom info")
                Threading.Thread.Sleep(1000)
                If pp(f_cnt) < 4 Then GoTo retry
            End If
        Catch exUsb As USB_exceptions
            Err_message(exUsb.Description)
            Return False
        Catch exComm As Comm_Exceptions
            Err_message(exComm.Description)
            Return False
        End Try
        Return True
    End Function
    Private Sub setUSBParameters()
        If lngHandle <> 0 Then
            Dim f_OverHeadRx As Integer = m_BikiInfo.MaxRxPacket \ 62
            If m_BikiInfo.MaxRxPacket Mod 62 <> 0 Then f_OverHeadRx += 1

            Dim f_OverHeadTx As Integer = m_BikiInfo.MaxTxPacket \ 62
            If m_BikiInfo.MaxTxPacket Mod 62 <> 0 Then f_OverHeadTx += 1

            FT_SetUSBParameters(lngHandle, m_BikiInfo.MaxRxPacket + (f_OverHeadRx * 2), m_BikiInfo.MaxTxPacket + (f_OverHeadTx * 2))
        End If
    End Sub
End Class
